package com.gopay.webtest.controller;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gopay.webtest.util.SignUtil;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.gopay.webtest.util.ApiUtil;
import com.gopay.webtest.util.BaseSign;
import com.gopay.webtest.vo.CommonResp;
import com.gopay.webtest.vo.ExPayCacheMock;

/**
 * 商户后台通知
 * 
 * @author 曹永峰
 * 
 */
@Controller
public class BackgroundMerController {
	@Resource(name = "signHandler")
	private Map<String, Object> signHandler = new HashMap<String, Object>();

	private static Logger logger = Logger.getLogger(BackgroundMerController.class);

	/**
	 * 处理返回的商户通知
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping("/result/webclient/background")
	public @ResponseBody String resResult(HttpServletRequest request, HttpServletResponse response)
			throws UnsupportedEncodingException {

		request.setCharacterEncoding("gbk");
		ServletRequestDataBinder binder = null;

		logger.info("************************* 接收到返回参数 *****************************");
		for (@SuppressWarnings("unchecked")
		Enumeration<String> enumeration = request.getParameterNames(); enumeration.hasMoreElements();) {
			String eleName = enumeration.nextElement();
			String eleValue = request.getParameter(eleName);
			if (logger != null) {
				logger.info(eleName + "=" + eleValue);
			}
		}
		logger.info("***************************************************************");
		CommonResp payinfo = new CommonResp();
		binder = new ServletRequestDataBinder(payinfo);
		binder.bind(request);

		String origSignMsg = payinfo.getSignValue();

		//获得签名类型，如果是签名类型是3，根据签名类型代码逻辑跟之前区分开
		String signType = payinfo.getSignType();
		String signStrb = null; //原串

		for (Enumeration enumeration = request.getParameterNames(); enumeration.hasMoreElements();) {
			String eleName = (String) enumeration.nextElement();
			String eleValue = request.getParameter(eleName);
			if (logger != null) {
				logger.error("map key: [" + eleName + "]，value: [" + eleValue+ "]");
			}
		}

		try {
			logger.info("ready to encrypted message with md5 or sha ...");

			String[] arrSplit = payinfo.getBackgroundMerUrl().split("[?]");
			String id = "";
			for (String string : arrSplit) {
				String[] param = string.split("=");
				if ("id".equals(param[0])) {
					id = param[1];
				}
			}
			payinfo.setVerficationCode(id);
			String signMapKey = payinfo.getTranCode();

			if (payinfo.getTranCode().equals("GS06") || payinfo.getTranCode().equals("GS09")
					|| payinfo.getTranCode().equals("GS03") || payinfo.getTranCode().equals("GS02")) {// G商融通
				// 充值/提现/还款，返回报文加密与上传加密字段不一致，单独处理
				if (payinfo.getTranCode().equals("GS09") || payinfo.getTranCode().equals("GS03")
						|| payinfo.getTranCode().equals("GS02")) {
					signMapKey = payinfo.getTranCode() + "_2.1_PC" + "_RESP";
				}
				signMapKey = payinfo.getTranCode() + "_2.1_PC";
			} else if (payinfo.getTranCode().equals("GC01")// 出金、入金、收益划拨返回报文和上送报文加密明文不一致，特殊处理
															// ，增加P2P转账、充值、提现、签约
					|| payinfo.getTranCode().equals("GC02") || payinfo.getTranCode().equals("GC03")
					|| payinfo.getTranCode().equals("GP01") || payinfo.getTranCode().equals("GP02")
					|| payinfo.getTranCode().equals("GP03") || payinfo.getTranCode().equals("GP05")
					|| payinfo.getTranCode().equals("GS01")) {
				if (payinfo.getTranCode().equals("GS01")) {
					signMapKey = payinfo.getTranCode() + "_RESP_PC";
				} else {
					signMapKey = payinfo.getTranCode() + "_RESP";
				}
			} else if (payinfo.getTranCode().equals("8801") || payinfo.getTranCode().equals("8803")
					|| payinfo.getTranCode().equals("SC01") || payinfo.getTranCode().equals("DS05")) {
				signMapKey = payinfo.getTranCode() + "_" + payinfo.getVersion() + "_NOTIFY";
			} else if (!payinfo.getTranCode().equals("9999") && !payinfo.getTranCode().equals("4010")) {
				signMapKey = payinfo.getTranCode() + "_" + payinfo.getVersion();
			}

			BaseSign handler = (BaseSign) signHandler.get(signMapKey);
			if (handler == null) {
				throw new Exception("没有符合signMapKey为：【" + signMapKey + "】的加签方式，无法进行加签处理");
			}


			// 进行加签
			handler.sign(signMapKey, "signType", "signValue", payinfo, request);


			if("3".equals(signType)){
				signStrb = handler.getSignStr(signMapKey,payinfo);
			}else{
				// 进行加签
				handler.sign(signMapKey, "signType", "signValue", payinfo, request);
			}


			logger.info("end encrypted message with md5 or sha ...");
		} catch (Exception e) {
			payinfo.setRespCode("MR08");
			e.printStackTrace();
		}

		// Attestation not through
		String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
				+ request.getContextPath();

		// 央行检测 不返回jumpUrl edit by fanghw 20160121
		StringBuffer url = new StringBuffer("RespCode=0000|JumpURL=" + basePath + "/jumpUrl.do");

		if("3".equals(signType)){
		    
		    String envName = (String) request.getSession().getAttribute("gopay_webtest_URL_Name");
	        ApiUtil.setEnvName(envName);
		    
			//进行加签验证
			boolean bverify = SignUtil.doCheck(signStrb,origSignMsg);
			if(!bverify){
				logger.info("not equal encrypted message ...");
				payinfo.setRespCode("MR07");
				logger.info("Attestation not through...");
			}
		}else{
			if (!origSignMsg.equals(payinfo.getSignValue())) {
				logger.info("not equal encrypted message ...");
				payinfo.setRespCode("MR07");
				logger.info("Attestation not through...");
			}
		}

		// /**************
		if (payinfo.getTranCode().equals("GC01") || payinfo.getTranCode().equals("GC02")
				|| payinfo.getTranCode().equals("GC03")) {
			logger.info("收到大宗交易后台返回数据！交易信息：" + payinfo.toString());
			// 返回信息成功代码
			return "0000";
		} else if (payinfo.getTranCode().equals("GP05") || payinfo.getTranCode().equals("GP01")
				|| payinfo.getTranCode().equals("GP02") || payinfo.getTranCode().equals("GP03")) {
			logger.info("收到P2P交易后台返回数据！交易信息：" + payinfo.toString());
			// 返回信息成功代码
			return "0000";
		} else if (payinfo.getTranCode().equals("GS06") || payinfo.getTranCode().equals("GS01")
				|| payinfo.getTranCode().equals("GS09") || payinfo.getTranCode().equals("GS03")
				|| payinfo.getTranCode().equals("GS02")) {
			logger.info("收到G商融通交易后台返回数据！交易信息：" + payinfo.toString());
			return "0000";

        } else if (payinfo.getTranCode().equals("7024")) {
            logger.info("收到汇款api通知交易后台返回数据！交易信息：" + payinfo.toString());
            return "0000";
        }
		// /**************
		String id = UUID.randomUUID().toString();
		request.getSession().getServletContext().setAttribute(id, payinfo);

		// 增加缓存数据
		ExPayCacheMock.addObj(payinfo.getOrderId(), payinfo);
		if (payinfo.getRespCode() != null && payinfo.getRespCode().equals("0000")) {
			return url.toString() + "?id=" + id;
		} else {
			return null;

		}

	}

	/**
	 * 展示交易结果
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/jumpUrl")
	public ModelAndView result(HttpServletRequest request, HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView();
		String id = request.getParameter("id");
		if (id == null || id.equals("")) {
			throw new Exception("获取返回信息失败");
		}

		ServletRequestDataBinder binder = null;

		CommonResp payinfo = new CommonResp();
		binder = new ServletRequestDataBinder(payinfo);
		binder.bind(request);
		logger.info("网关通知详情:" + JSONObject.fromObject(payinfo));
		payinfo = CommonResp.formatProperty(payinfo);
		StringBuffer url = new StringBuffer("gopay.webtest.back_res");

		if (payinfo.getCharset() == null || payinfo.getCharset().equals("1")) {
			url.append("_gbk");
		}
		mav.setViewName(url.toString());
		mav.addObject("payinfo", payinfo);
		return mav;
	}

	@RequestMapping("/jumpUrl_expay")
	public ModelAndView result_expay(HttpServletRequest request, HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView();
		String id = request.getParameter("orderId");
		if (id == null || id.equals("")) {
			throw new Exception("获取返回信息失败");
		}

		CommonResp payinfo = (CommonResp) ExPayCacheMock.getObject(id);
		logger.info("从缓存中获取payinfo--orderId=" + id);
		StringBuffer url = new StringBuffer("gopay.webtest.back_res");

		if (payinfo.getCharset() == null || payinfo.getCharset().equals("1")) {
			url.append("_gbk");
		}
		mav.setViewName("gopay.webtest.back_res");
		mav.addObject("payinfo", payinfo);

		// ExPayCacheMock.remove(id); 暂不删除 等待 自己销毁

		return mav;
	}
}
